<template>
  <div class="comments" :class="[lineClass]" @scroll="onScroll">
    <CommentContainer :feed-id="feedId" :comments="comments" :is-loading="loading" :no-more="noMore">
      <template #default="{ id, comment }">
        <div class="head gap-row-5">
          <Avatar
            :src="comment.author?.avatar"
            :radius="10"
            :vip="comment.author.is_vip"
            :vipTier="comment.author.tier"
          ></Avatar>
          <div class="nickname font-size-14 font-weight-500 line-height-140 gap-row-4">
            <Icon :name="`vip${comment.author.tier || 1}`" size="24"></Icon>
            <span>{{ comment.author?.nickname }}</span>
            <PremiumStar v-if="comment.author.is_vip"></PremiumStar>
          </div>
          <LikeButton :id="comment.id" :is-like="comment.liked"></LikeButton>
        </div>
        <div class="content font-size-14 font-weight-400 line-height-140">
          {{ comment.content }}
        </div>
        <div class="foot gap-row-8">
          <div class="time font-size-12 font-weight-400 line-height-120 text-subtitle-x">
            {{ formatTime(comment.created_at) }}
          </div>
          <div
            class="reply font-size-12 font-weight-400 line-height-120 text-subtitle-x pointer"
            @click="reply(id, comment)"
          >
            {{ $t('message.reply') }}
          </div>
        </div>
      </template>
    </CommentContainer>
  </div>
  <div v-if="!isLogin" class="divider bg-input"></div>
  <div class="feature gap-row-16" :class="[lineClass]" ref="feature">
    <Avatar v-if="isLogin" :src="userData.avatar" :radius="20" :vip="isVip" :vipTier="userData.tier"></Avatar>
    <div v-if="isLogin" class="input gap-row-16 bg-surface" :class="[lineClass]">
      <textarea
        v-model="message"
        class="font-size-14 font-weight-400 line-height-140"
        :class="[lineClass]"
        type="text"
        :placeholder="$t('placeholder.message')"
        ref="textarea"
      />
      <button class="send" @click="submit"><Icon size="20" name="send"></Icon></button>
    </div>
    <div v-if="!isLogin" class="font-size-14 font-weight-500 line-height-140 text-input pointer" @click="toLogin">
      <span class="text-primary">{{ $t('label.login') }}</span>
      {{ '/' }}
      <span class="text-primary">{{ $t('label.register') }}</span>
      {{ $t('label.canSendMessage') }}
    </div>
  </div>
</template>

<script setup>
import { debounce } from 'lodash-es'
import { computed, ref, shallowRef, watch } from 'vue'
import { storeToRefs } from 'pinia'
import { useAccountStore } from '@/store/account'
import { useAuthDialogStore } from '@/store/auth-dialog'
import { useChatPanelStore } from '@/store/chat-panel'
import { usePopupDialogStore } from '@/store/popup-dialog'
import { $t } from '@/i18n'
import { tsSecondToHumanString } from '@/utils/string-helper'
import PremiumStar from '@/components/common/PremiumStar.vue'
import Avatar from '@/components/multimedia/Avatar.vue'
import { usePreventTouchmove } from '@/compositions/mobile/preventTouchmove'
import { useInfinite } from '@/compositions/request/infinite'
import API from '@/http'
import CommentContainer from './CommentContainer.vue'
import LikeButton from './LikeButton.vue'

const props = defineProps({
  feedId: { type: Number },
})

const accountStore = useAccountStore()
const { userData, isLogin, isVip } = storeToRefs(accountStore)
const { afterLoginAction } = accountStore

const { open: openAuth } = useAuthDialogStore()
const { close: closeChatPanel } = useChatPanelStore()
function toLogin() {
  closeChatPanel()
  openAuth()
}

const {
  dataList: comments,
  loading,
  noMore,
  // errorMsg,
  init,
  refresh,
  nextPage,
} = useInfinite({ request: API.Comment.list, params: { id: props.feedId } })
init()

watch(
  () => props.feedId,
  (v) => {
    refresh({ newParams: { id: v } })
  },
)

const message = ref('')
const textarea = ref(null)
const lineClass = computed(() => {
  return 'line-' + Math.min(message.value.split('\n').length, 4)
})
const replayId = ref(null)
const replyTagTo = shallowRef(null)
const reply = afterLoginAction($reply)
function $reply(id, comment) {
  replayId.value = id
  replyTagTo.value = comment
  const msgArr = message.value.split(' ')
  if (msgArr.length > 0) {
    msgArr[0] = `@${comment.author?.nickname}${msgArr.length === 1 ? ' ' : ''}`
  }
  message.value = msgArr.join(' ')

  textarea.value.focus()
}
watch(message, (v) => {
  if (v === '') {
    replyTagTo.value = null
  }
})

const { $alert } = usePopupDialogStore()
const sending = ref(false)
function submit() {
  if (sending.value) return

  const data = {
    info_id: props.feedId,
    content: message.value.trim(),
  }
  if (replyTagTo.value !== null) {
    data.reply_comment_id = replayId.value
    // 送去後端的內容要把 @nickname 拿掉
    data.content = data.content.substring(replyTagTo.value.author?.nickname.length + 1).trim()
  }
  if (!data.content) return

  sending.value = true
  API.Comment.add({ data })
    .then(() => {
      refresh()
      message.value = ''
    })
    .catch((e) => {
      $alert({
        content: e.message,
      }).open()
    })
    .finally(() => (sending.value = false))
}

const feature = ref(null)
usePreventTouchmove(feature)

const onScroll = debounce(({ target: { scrollTop, clientHeight, scrollHeight } }) => {
  // 觸底繼續加載
  if (scrollTop + clientHeight >= scrollHeight - 10) {
    nextPage()
  }
}, 200)

function formatTime(time) {
  const v = tsSecondToHumanString(time, time.toLocaleString('af'))
  return typeof v === 'string' ? v : $t(v.key, v.values)
}
</script>

<style lang="scss" scoped>
@mixin line($startVal, $count) {
  @for $i from 1 through $count {
    &.line-#{$i} {
      height: #{$startVal + 1.25rem * $i};
    }
  }
}
@mixin line2($startVal, $count) {
  @for $i from 1 through $count {
    &.line-#{$i} {
      height: calc(100% - #{$startVal + 1.25rem * $i});
    }
  }
}

.comments {
  display: flex;
  flex-direction: column;
  overflow: auto;
  @include line2(2.25rem, 4);

  .head {
    margin-left: 0.125rem;
    display: flex;
    align-items: center;
    .nickname {
      flex-grow: 1;
      display: flex;
      align-items: center;
    }
  }

  .content {
    margin-left: 0.125rem;
    padding-right: 1.5rem;
    letter-spacing: 0.2px;
    white-space: pre-wrap;
  }

  .foot {
    margin-left: 0.125rem;
    display: flex;
  }
}

.divider {
  width: calc(100% + 2rem);
  height: 1px;
  margin-left: -1rem;
}

.feature {
  margin-left: 0.125rem;
  padding: 0.5rem 0;
  display: flex;
  align-items: center;
  @include line(2.25rem, 4);

  .avatar {
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 2.5rem;
    background: aquamarine;
    align-self: flex-end;
  }

  .input {
    flex-grow: 1;
    padding: 0.625rem 1rem;
    border-radius: 0.75rem;
    display: flex;
    justify-content: center;
    align-items: flex-end;
    @include line(1.25rem, 4);

    textarea {
      flex-grow: 1;
      outline: none;
      resize: none;

      @include line(0rem, 4);
    }

    .send {
      display: flex;
      align-items: center;
    }
  }
}
</style>
